package com.ty.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;

import cn.smart.core.exception.BizException;
import com.ty.dao.ProductDao;

import com.ty.dto.product.Product;
import com.ty.entity.ProductEntity;
import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class ProductService {

    @Autowired
    ProductDao productDao;
    @Resource(name = "redisTemplate")
    ValueOperations<String, Product> valueOperations;

    @Resource(name = "redisTemplate")
    HashOperations<String, String,String> hashOperations;


    private static final String BLACK_KEY = "product:black";



    //2.使用黑名单解决缓存穿透问题
    public Product select(Integer id)
    {
        log.debug("查询商品信息{}",id);
        //1.先看redis有没有
        Product product =  valueOperations.get("product:" + id);
        if (ObjectUtil.isNotEmpty( product)){
            return product;
        }
        //2.不存在redis，看看有没有在黑名单
        Boolean b = hashOperations.hasKey(BLACK_KEY, "product:" + id);
        if(b){
            log.error("商品在黑名单id：{}", id);
            BizException.throwException(410,"商品不存在");
        }

        //3.不在黑名单 ，product == null,去数据库查
        ProductEntity productEntity = productDao.select(id);
        if(ObjectUtil.isEmpty(productEntity)){
            //4.放进黑名单
            log.debug("商品放进黑名单id：{}", id);
            hashOperations.put(BLACK_KEY, "product:" + id, DateUtil.now());
            BizException.throwException(410,"商品不存在");
        }
        //5.保存到redis
        log.debug("商品保存到Redis,  id：{}", id);

        product = BeanUtil.copyProperties(productEntity, Product.class);

        valueOperations.set("product:" + id, product, 60 * 60 * 23 + RandomUtil.randomInt(3600), TimeUnit.SECONDS);
        return product;
    }
}